﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Windows.Forms.Design;
using System.Runtime.Serialization;

namespace VoltcraftControlInterface
{
    public partial class MainForm : Form
    {
        ToolTip info;
        string editmode;
        bool shouldlogHeat;
        public DataTable listofmediums;
        PolynomialIntegrator poli;
        public delegate void SetVDel(double T2, double T1, double t2, double t1, double elapsed, double now);
        public void SetValues(double T2, double T1, double t2, double t1, double elapsed, double now)
        {
            if (this.heatbalanceBox.InvokeRequired)
            {
                SetVDel d = new SetVDel(SetValues);
                Invoke(d, new object[] { T2, T1, t2, t1, elapsed, now });
            }
            else
            {
                DataRow[] resultrow = listofmediums.Select("Name = '" + mediumList.Text + "'");
                if (resultrow.Length > 0)
                {
                    poli.IntegrateAndCalculate(resultrow[0]["Expression"].ToString(), T2, T1, t2, t1);
                    heatbalanceBox.Text = String.Format("{0:0.000}", (Convert.ToDouble(heatbalanceBox.Text) + poli.DeltaQ));
                    powerBox.Text = poli.Pow.ToString("F3");
                    if (shouldlogHeat)
                    {
                        heatChart.Series[0].Points.AddXY(elapsed, Convert.ToDouble(heatbalanceBox.Text), now);
                        heatChart.Series[1].Points.AddXY(elapsed, Convert.ToDouble(poli.Pow));
                    }
                }
            }
        }

        private void startheatlogging_Click(object sender, EventArgs e)
        {
            Double maxval = 0;
            if (heatChart.Series[0].Points.Count > 0) maxval = heatChart.Series[0].Points.Last().XValue;
            if ((logger.Elapsed.TotalSeconds+1) >= maxval)
            {
                shouldlogHeat = true;
                tsbutton1.Enabled = false;
                tsbutton2.Enabled = true;
            }
            else
            {
                MessageBox.Show("Can't overwrite old chart data! First clear the chart or create a new experiment", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void stopheatlogging_Click(object sender, EventArgs e)
        {
            shouldlogHeat = false;
            tsbutton1.Enabled = true;
            tsbutton2.Enabled = false;
        }

        private void exportHeatCSV_Click(object sender, EventArgs e)
        {
            SaveFileDialog filepath = new SaveFileDialog();
            filepath.Filter = "CSV Spreadsheet|*.csv";
            filepath.Title = "Save Logged Data";
            filepath.ShowDialog();
            if (filepath.FileName != "")
            {
                if (System.IO.File.Exists(filepath.FileName)) System.IO.File.Delete(filepath.FileName);
                using (System.IO.StreamWriter file =
              new System.IO.StreamWriter(@filepath.FileName, true))
                {
                        string line = "Time(s);Time;Heat balance (KJ/kg);Heat Exchange Rate (KW/kg)";
                        file.WriteLine(line);
                        for (int i = 0; i < heatChart.Series[0].Points.Count; i++)
                        {
                            //parsetime = DateTime.FromOADate(logChart.Series["Voltage"].Points[i].XValue);
                            file.WriteLine(heatChart.Series[0].Points[i].XValue + ";" + DateTime.FromOADate(heatChart.Series[0].Points[i].YValues[1]).ToLongTimeString() + "." + DateTime.FromOADate(heatChart.Series[0].Points[i].YValues[1]).Millisecond + ";" + heatChart.Series[0].Points[i].YValues[0].ToString("F3") + ";" + heatChart.Series[1].Points[i].YValues[0].ToString("F3"));
                        }
                    file.Close();

                }
            }
        }

        private void clearHeatChart_Click(object sender, EventArgs e)
        {
            heatChart.Series[0].Points.Clear();
            heatChart.Series[1].Points.Clear();
            heatbalanceBox.Text = "0";
            powerBox.Text = "0";
        }

        private void addPolynomialInterpolatedFunctionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //InputClass input = new InputClass();
            if (!okBtn.Enabled)
            {
                exprBox.Text = "Ax^n+Bx^(n-1)+Cx^(n-2)+...+D";
                matBox.Text = "Material Name";
                editmode = "add";
                /*if (input.InputBox("Input", "Insert name of material", "Insert interpolated expression", ref returnname, ref returnexpr, this) != DialogResult.Cancel)
                {
                    if ((returnexpr != "") && (returnname != ""))
                    {
                        DataRow newrow = listofmediums.NewRow();
                        newrow["Name"] = returnname;
                        newrow["Expression"] = returnexpr;
                        listofmediums.Rows.Add(newrow);
                        mediumList.Items.Add(returnname);
                    }
                }*/
                okBtn.Enabled = true;
                cancBtn.Enabled = true;
                addTsBtn.Enabled = false;
                delTsBtn.Enabled = false;
                editTsBtn.Enabled = false;
                clrTsBtn.Enabled = false;
                Pnl pnlAnim = new Pnl();
                pnlAnim.openPnl(ref inputPnl);
            }
        }

        private void deleteSelectedEntryInMaterialsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (mediumList.Text != "")
            {
                DataRow todelete = listofmediums.Select("Name = '" + mediumList.Text + "'")[0];
                listofmediums.Rows.Remove(todelete);
                int tmpindex = mediumList.SelectedIndex;
                mediumList.Items.RemoveAt(mediumList.SelectedIndex);
                if (mediumList.Items.Count!=0)
                {
                    if (tmpindex == 0)
                        mediumList.SelectedIndex = 0;
                    else mediumList.SelectedIndex = tmpindex - 1;
                }
                
            }
        }

        private void deleteALLentriesInMaterialsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to delete all entries of materials list?", "Warning!", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                listofmediums.Rows.Clear();
                mediumList.Items.Clear();
            }
        }

        private void showEdit_Click(object sender, EventArgs e)
        {
            if (!okBtn.Enabled)
            {
                DataRow[] resultrow = listofmediums.Select("Name = '" + mediumList.Text + "'");
                if (resultrow.Length > 0)
                {
                    exprBox.Text = resultrow[0]["Expression"].ToString();
                    matBox.Text = resultrow[0]["Name"].ToString();
                    editmode = "edit";
                    Pnl anim = new Pnl();
                    anim.openPnl(ref inputPnl);
                    okBtn.Enabled = true;
                    cancBtn.Enabled = true;
                    addTsBtn.Enabled = false;
                    delTsBtn.Enabled = false;
                    editTsBtn.Enabled = false;
                    clrTsBtn.Enabled = false;
                }
            }
        }

        private void okBtn_Click(object sender, EventArgs e)
        {
            if ((matBox.Text != "") && (exprBox.Text != ""))
            {
                try
                {
                    PolynomialIntegrator test = new PolynomialIntegrator();
                    test.IntegrateAndCalculate(exprBox.Text, 300, 299, 1, 0);
                }
                catch
                {
                    err.Hide(this);
                    err.ToolTipTitle = "Error!";
                    err.ToolTipIcon = ToolTipIcon.Error;
                    err.IsBalloon = false;
                    err.Show("The expression you entered can't be parsed. Please check if it follows the guidelines provided in the help (?) button!", this, exprBox.Location, 3500);
                    //MessageBox.Show("The expression you entered can't be parsed. Please check if it follows the guidelines provided in the help (?) button!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (editmode == "add")
                {
                    DataRow newrow = listofmediums.NewRow();
                    newrow["Name"] = matBox.Text;
                    newrow["Expression"] = exprBox.Text;
                    listofmediums.Rows.Add(newrow);
                    mediumList.Items.Add(matBox.Text);
                }
                else if (editmode == "edit")
                {
                    DataRow[] resultrow = listofmediums.Select("Name = '" + mediumList.Text + "'");
                    DataRow newrow = listofmediums.NewRow();
                    newrow["Name"] = matBox.Text;
                    newrow["Expression"] = exprBox.Text;
                    listofmediums.Rows.Remove(resultrow[0]);
                    listofmediums.Rows.Add(newrow);
                    mediumList.Items[mediumList.SelectedIndex] = matBox.Text;
                }
            }
            okBtn.Enabled = false;
            cancBtn.Enabled = false;
            Pnl anim = new Pnl();
            anim.closePnl(ref inputPnl);
            editmode = "";
            addTsBtn.Enabled = true;
            delTsBtn.Enabled = true;
            editTsBtn.Enabled = true;
            clrTsBtn.Enabled = true;
        }

        private void cancBtn_Click(object sender, EventArgs e)
        {
            Pnl anim = new Pnl();
            anim.closePnl(ref inputPnl);
            okBtn.Enabled = false;
            cancBtn.Enabled = false;
            editmode = "";
            addTsBtn.Enabled = true;
            delTsBtn.Enabled = true;
            editTsBtn.Enabled = true;
            clrTsBtn.Enabled = true;
        }

        private void helpBtn_Click(object sender, EventArgs e)
        {
            /*MessageBox.Show("You can use only polynomial expression of x, always indicating coefficient and power of x" + Environment.NewLine +
                "Example: if you need to write the variable x (coefficient 1 and power 1), you must write 1x^1" + Environment.NewLine +
                "You can write numbers in scientific notation, for example for 3*10^5 you write 3e5, for 2*10^(-6) you write 2e-6", "Help", MessageBoxButtons.OK, MessageBoxIcon.Information);*/
            info.Hide(this);
            info.IsBalloon = false;
            info.ToolTipTitle = "Help";
            info.ToolTipIcon = ToolTipIcon.Info;
            info.Show("You can use only polynomial expression of x, always indicating coefficient and power of x" + Environment.NewLine +
                "Example: if you need to write the variable x (coefficient 1 and power 1), you must write 1x^1" + Environment.NewLine +
                "You can write numbers in scientific notation, for example for 3*10^5 you write 3e5, for 2*10^(-6) you write 2e-6"
                , this, new Point(button1.Location.X, button1.Location.Y+100), 10000);
        }
    }
}
